import sys
import numpy as np
import faiss
import time
import threading
import json
import re
import traceback

from typing import Optional, List
from fastapi import FastAPI, Form
from pydantic import BaseModel

from face_embedding.faiss_search import faiss_search_embedding, init_faiss, refresh_faiss, delete_faiss_embedding, add_faiss_embedding

from utils import dbpool_util

app = FastAPI()

def get_db():
    return dbpool_util

def query_db(query, args=(), one=False):
    # print('sql_s1', query, file=sys.stdout)
    result = get_db().execute_query(query, args)
    return result


class FaceSearchParam(BaseModel):
    groupId: str
    embedding: str
    top_n: int
    threshold: float

@app.post("/face_search")
async def face_search(face_param: FaceSearchParam):
    try:
        groupId = face_param.groupId
        embedding_str = face_param.embedding
        top_n = face_param.top_n
        if top_n is None:
            top_n = 3
        else:
            top_n = int(top_n)
        threshold = face_param.threshold
        if threshold is None:
            threshold = 0.9
        else:
            threshold = float(threshold)
        # print(embedding_str)
        embedding = json.loads(embedding_str)
        error, userCode,I,D = faiss_search_embedding(groupId, embedding, top_n, threshold)
        print(D, I)
        return {
            'code': 1,
            'data': {
                'userCode': userCode,
                'D': D,
                'I': I
            }
        }
    except Exception as e:
        traceback.print_exc()  ###
        return {
            'code': -1,
            'message': '异常错误'
        }

class FaceAddParam(BaseModel):
    groupId: str
    embedding: str
    faceId: str


@app.post("/face_add")
async def face_add(face_param: FaceAddParam):
    try:
        groupId = face_param.groupId
        faceId = face_param.faceId
        embedding_str = face_param.embedding
        embeddings = json.loads(embedding_str)
        add_faiss_embedding(groupId, faceId, embeddings)
        return {
            'code': 1
        }
    except Exception as e:
        traceback.print_exc()  ###
        return {
            'code': -1,
            'message': '异常错误'
        }

class FaceGroupParam(BaseModel):
    groupId: str

@app.post("/delete_group")
async def delete_group(face_param: FaceGroupParam):
    try:
        groupId = face_param.groupId
        delete_faiss_embedding(groupId)
        return {
            'code': 1
        }
    except Exception as e:
        traceback.print_exc()  ###
        return {
            'code': -1,
            'message': '异常错误'
        }

@app.post("/face_reload")
async def face_reload(face_param: FaceGroupParam):
    try:
        groupId = face_param.groupId
        refresh_faiss(groupId, get_db())
        return {
            'code': 1
        }
    except Exception as e:
        traceback.print_exc()  ###
        return {
            'code': -1,
            'message': '异常错误'
        }

@app.get("/")
def index():
    return 'faiss service is runing.'

# 初始化faiss
init_faiss(dbpool_util)

# if __name__ == '__main__':
#     app.run(host='0.0.0.0', port=17111)

# uvicorn faiss_server_fastapi:app --host 0.0.0.0 --port 17111 --workers 1

